#include "stdint.h"
#include "stdio.h"
#include "n32g031.h"
#include "DevicesSoftTimer.h"
#include "DevicesBuzz.h"




static BuzzInfoType st_typeBuzzInfo = {0};

/* 周期调用计数 */
volatile static uint32_t st_uiBuzzTickCnt = 0;


SoftTimerTypeDef g_typeSoftTimerBuzzHanle = {0};


void vSoftTimerBuzzCallbackFunction(void *pvHandle)
{
    (void)pvHandle;

    vBuzzMachine();
}


void vBuzzInit(void)
{
    GPIO_InitType GPIO_InitStructure = {0};


    st_typeBuzzInfo.periph = BUZZ_GPIO_Port;
    st_typeBuzzInfo.pin = BUZZ_Pin;


    /* -1- Enable GPIOx Clock (to be able to program the configuration registers) */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);

    /* -2- Configure GPIOx_PIN in output push-pull mode */
    GPIO_InitStruct(&GPIO_InitStructure);
    GPIO_InitStructure.Pin = st_typeBuzzInfo.pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_HIGH;
    GPIO_InitPeripheral(st_typeBuzzInfo.periph, &GPIO_InitStructure);

    BUZZ_OPEN();


    /* 软件定时器周期调用 */
    cSoftTimerCreateMs(&g_typeSoftTimerBuzzHanle, 100, softTimerOpen | softTimerCircular, vSoftTimerBuzzCallbackFunction);

    vBuzzSetStatus(BUZZ_FLASH_FAST_DISABLE_CNT, 3);
}

/*
 * Return:      void
 * Parameters:  usChannel: LED通道; usChannel: 状态; usChannel: 闪烁次数/或者占空比;
 * Description: 设置LED状态
 */
void vBuzzSetStatus(BuzzStateEnum enumStatus, uint8_t ucCnt)
{
    st_typeBuzzInfo.state = enumStatus;
    st_typeBuzzInfo.flashCnt = ucCnt * 2 - 2;
}

/*
 * Return:      void
 * Parameters:  *ptypeBuzz: Buzz信息结构体
 * Description: Buzz状态刷新
 */
void vBuzzStateMachine(BuzzInfoType *ptypeBuzz)
{
    switch(ptypeBuzz->state)
    {
        /* 关闭 */
        case BUZZ_DISABLE:
            GPIO_ResetBits(ptypeBuzz->periph, ptypeBuzz->pin);
            ptypeBuzz->state = BUZZ_IDLE;
            break;

        /* 常亮 */
        case BUZZ_ENABLE:
            GPIO_SetBits(ptypeBuzz->periph, ptypeBuzz->pin);
            ptypeBuzz->state = BUZZ_IDLE;
            break;

        /* 快闪/快闪后关闭/快闪后常亮 */
        case BUZZ_FLASH_SLOW:
        case BUZZ_FLASH_SLOW_DISABLE_CNT:
        case BUZZ_FLASH_SLOW_ENABLE_CNT:
            if((st_uiBuzzTickCnt % 4) == 0)
            {
                GPIO_TogglePin(ptypeBuzz->periph, ptypeBuzz->pin);

                if((ptypeBuzz->state != BUZZ_FLASH_SLOW) && ((ptypeBuzz->flashCnt--) <= 0))
                {
                    ptypeBuzz->state = (ptypeBuzz->state == BUZZ_FLASH_SLOW_ENABLE_CNT) ? BUZZ_ENABLE : BUZZ_DISABLE;
                }
            }
            break;

        /* 慢闪/慢闪后关闭/慢闪后常亮 */
        case BUZZ_FLASH_FAST:
        case BUZZ_FLASH_FAST_DISABLE_CNT:
        case BUZZ_FLASH_FAST_ENABLE_CNT:
            if((st_uiBuzzTickCnt % 2) == 0)
            {
                GPIO_TogglePin(ptypeBuzz->periph, ptypeBuzz->pin);

                if((ptypeBuzz->state != BUZZ_FLASH_FAST) && ((ptypeBuzz->flashCnt--) <= 0))
                {
                    ptypeBuzz->state = (ptypeBuzz->state == BUZZ_FLASH_FAST_ENABLE_CNT) ? BUZZ_ENABLE : BUZZ_DISABLE;
                }
            }
            break;

        default : break;
    }
}

void vBuzzMachine(void)
{
    /* 所有Buzz使用同一个状态机变量，以方便实现一致的闪烁步调 */
    ++st_uiBuzzTickCnt;

    vBuzzStateMachine(&st_typeBuzzInfo);
}

BuzzInfoType *ptypeBuzzGetInfo(void)
{
    return &st_typeBuzzInfo;
}
